
#include <gfx/programparametername.h>
#include <stdio.h>

ceProgramParameterNameManager* ceProgramParameterNameManager::static_instances = 0;

ceProgramParameterNameManager::ceProgramParameterNameManager ()
	: _count(0)
{
	_ids.clear();
	_names.clear ();

	// Register the default names directly taken from the
  // ceProgramParameterBinding enum
  AddName("MATRIX_PROJECTION");
  AddName("MATRIX_VIEW");
  AddName("MATRIX_WORLD");
  AddName("LIGHT_AMBIENT");
  AddName("LIGHT_DIFFUSE");
  AddName("LIGHT_SPECULAR");
  AddName("LIGHT_POSITION");
	AddName("LIGHT_ATTENUATION");
  AddName("MATERIAL_AMBIENT");
  AddName("MATERIAL_DIFFUSE");
  AddName("MATERIAL_SPECULAR");
  AddName("MATERIAL_SHININESS");
  AddName("MATERIAL_EMISSION");
  AddName("POSITION0");
  AddName("POSITION1");
  AddName("NORMAL0");
  AddName("NORMAL1");
	AddName("TANGENT0");
	AddName("TANGENT1");
	AddName("BINORMAL0");
	AddName("BINORMAL1");
	AddName("TEXCOORD0");
  AddName("TEXCOORD1");
  AddName("TEXCOORD2");
  AddName("TEXCOORD3");
  AddName("TEXCOORD4");
  AddName("TEXCOORD5");
  AddName("TEXCOORD6");
  AddName("INDEX");
  AddName("BLEND");
  AddName("TEXTURE0");
  AddName("TEXTURE1");
  AddName("TEXTURE2");
  AddName("TEXTURE3");
  AddName("TEXTURE4");
  AddName("TEXTURE5");
  AddName("TEXTURE6");
  AddName("TEXTURE7");
	AddName("SHADOWMAP0MATRIX");
	AddName("SHADOWMAP1MATRIX");
	AddName("SHADOWMAP2MATRIX");
  AddName("SKELETON_BONES");
}

ceProgramParameterNameManager* ceProgramParameterNameManager::Get()
{
	if (!ceProgramParameterNameManager::static_instances)
		{
			ceProgramParameterNameManager::static_instances = new ceProgramParameterNameManager();
		}
	return ceProgramParameterNameManager::static_instances;
}

unsigned ceProgramParameterNameManager::GetNumberOfNames () const
{
	return _count;
}

std::string ceProgramParameterNameManager::GetName(int id) const
{
  std::map<int, std::string>::const_iterator it;
	it = _names.find(id);
	if (it == _names.end ())
		{
			// this id is not registered.
			// we cannot create a name so we simply return an empty string
      return std::string("");
		}
	return it->second;
}

int ceProgramParameterNameManager::AddName (const char *name)
{
  std::string sName (name);
  _ids[sName] = _count;
  _names[_count] = sName;
	_count++;
	return _count-1;
}

int ceProgramParameterNameManager::GetId (const char *name)
{
  std::string sName (name);

  std::map<std::string, int>::iterator it;
  it = _ids.find(sName);
  if (it == _ids.end ())
		{
      return AddName (name);
		}
	return it->second;
}


ceProgramParameterName::ceProgramParameterName(const ceProgramParameterName& other)
	: _name (other._name)
	, _id (other._id)
  , _valid (other._valid)
{
}

ceProgramParameterName::ceProgramParameterName ()
  : _name (std::string(""))
	, _id (-1)
  , _valid (false)
{
}

ceProgramParameterName::ceProgramParameterName(const char *name)
	: _name (name)
	, _id (ceProgramParameterNameManager::Get()->GetId(name))
{
  _valid = _id >= 0;
}

ceProgramParameterName::ceProgramParameterName(int id)
	: _name ("")
	, _id (id)
{
  _valid = _id >= 0;
}


const char* ceProgramParameterName::GetName()
{
  if (_id >= 0 && _name == std::string(""))
		{
			_name = ceProgramParameterNameManager::Get()->GetName(_id);
		}
  return _name.c_str();
}
